package com.why.zing.alipay.service.impl;

import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayResponse;
import com.alipay.api.request.AlipayTradeCancelRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.*;
import com.why.zing.alipay.builder.AlipayTradeCancelRequestBuilder;
import com.why.zing.alipay.builder.AlipayTradePrecreateRequestBuilder;
import com.why.zing.alipay.builder.AlipayTradeQueryRequestBuilder;
import com.why.zing.alipay.builder.AlipayTradeRefundRequestBuilder;
import com.why.zing.alipay.constant.Constants;
import com.why.zing.alipay.constant.TradeStatus;
import com.why.zing.alipay.result.AlipayF2FCancelResult;
import com.why.zing.alipay.result.AlipayF2FPrecreateResult;
import com.why.zing.alipay.result.AlipayF2FQueryResult;
import com.why.zing.alipay.result.AlipayF2FRefundResult;
import com.why.zing.alipay.service.AbstractAlipayService;
import com.why.zing.alipay.service.AlipayTradeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * 订单处理
 *
 * @author 睁眼看世界
 * @date 2020年1月10日
 */
@Slf4j
public class AlipayTradeServiceImpl extends AbstractAlipayService implements AlipayTradeService {

    @Autowired
    private AlipayClient client;

    /**
     * 当面付2.0消费查询
     */
    @Override
    public AlipayF2FQueryResult queryTradeResult(AlipayTradeQueryRequestBuilder builder) {

        validateBuilder(builder);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.putOtherTextParam(Constants.APP_AUTH_TOKEN, builder.getAppAuthToken());
        request.setBizContent(builder.toJsonString());
        log.info("trade.query param is [{}]", request.getBizContent());
        AlipayTradeQueryResponse response = (AlipayTradeQueryResponse) getResponse(client, request);
        log.info("trade.query result is [{}]", response);
        AlipayF2FQueryResult result = new AlipayF2FQueryResult(response);
        if (querySuccess(response)) {
            // 查询返回该订单交易支付成功
            result.setTradeStatus(TradeStatus.SUCCESS);
        } else if (tradeError(response)) {
            // 查询发生异常，交易状态未知
            result.setTradeStatus(TradeStatus.UNKNOWN);
        } else {
            // 其他情况均表明该订单号交易失败
            result.setTradeStatus(TradeStatus.FAILED);
        }
        return result;
    }

    /**
     * 当面付2.0消费退款
     */
    @Override
    public AlipayF2FRefundResult tradeRefund(AlipayTradeRefundRequestBuilder builder) {
        validateBuilder(builder);

        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setNotifyUrl(builder.getNotifyUrl());
        request.putOtherTextParam(Constants.APP_AUTH_TOKEN, builder.getAppAuthToken());
        request.setBizContent(builder.toJsonString());

        log.info("trade.refund param is [{}]", request.getBizContent());
        AlipayTradeRefundResponse response = (AlipayTradeRefundResponse) getResponse(client, request);
        log.info("trade.refund result is [{}]", response);

        AlipayF2FRefundResult result = new AlipayF2FRefundResult(response);
        if (response != null && Constants.SUCCESS.equals(response.getCode())) {
            // 退货交易成功
            result.setTradeStatus(TradeStatus.SUCCESS);
        } else if (tradeError(response)) {
            // 退货发生异常，退货状态未知
            result.setTradeStatus(TradeStatus.UNKNOWN);
        } else {
            // 其他情况表明该订单退货明确失败
            result.setTradeStatus(TradeStatus.FAILED);
        }
        return result;
    }


    /**
     * 当面付2.0预下单(生成二维码)
     */
    @Override
    public AlipayF2FPrecreateResult tradePrecreate(AlipayTradePrecreateRequestBuilder builder) {
        validateBuilder(builder);

        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setNotifyUrl(builder.getNotifyUrl());
        request.putOtherTextParam(Constants.APP_AUTH_TOKEN, builder.getAppAuthToken());
        request.setBizContent(builder.toJsonString());

        log.info("trade.precreate param is [{}]", request.getBizContent());
        AlipayTradePrecreateResponse response = (AlipayTradePrecreateResponse) getResponse(client, request);
        log.info("trade.precreate result is [{}]", response);

        AlipayF2FPrecreateResult result = new AlipayF2FPrecreateResult(response);
        if (response != null && Constants.SUCCESS.equals(response.getCode())) {
            // 预下单交易成功
            result.setTradeStatus(TradeStatus.SUCCESS);
        } else if (tradeError(response)) {
            // 预下单发生异常，状态未知
            result.setTradeStatus(TradeStatus.UNKNOWN);
        } else {
            // 其他情况表明该预下单明确失败
            result.setTradeStatus(TradeStatus.FAILED);
        }
        return result;
    }


    // 根据外部订单号outTradeNo撤销订单
    @Override
    public AlipayF2FCancelResult cancelTrade(AlipayTradeCancelRequestBuilder builder) {

        validateBuilder(builder);

        AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
        request.putOtherTextParam(Constants.APP_AUTH_TOKEN, builder.getAppAuthToken());
        request.setBizContent(builder.toJsonString());

        log.info("trade.cancel param is [{}]", request.getBizContent());
        AlipayTradeCancelResponse response = (AlipayTradeCancelResponse) getResponse(client, request);
        log.info("trade.cancel result is [{}]", response);

        AlipayF2FCancelResult result = new AlipayF2FCancelResult(response);
        if (cancelSuccess(response)) {
            // 取消订单成功
            result.setTradeStatus(TradeStatus.SUCCESS);
        } else if (tradeError(response)) {
            // 取消订单发生异常，状态未知
            result.setTradeStatus(TradeStatus.UNKNOWN);
        } else {
            // 其他情况表明该取消订单明确失败
            result.setTradeStatus(TradeStatus.FAILED);
        }
        return result;
    }


    /**
     * 查询返回“支付成功”
     */
    private boolean querySuccess(AlipayTradeQueryResponse response) {
        return response != null &&
                Constants.SUCCESS.equals(response.getCode()) &&
                ("TRADE_SUCCESS".equals(response.getTradeStatus()) ||
                        "TRADE_FINISHED".equals(response.getTradeStatus())
                );
    }

    /**
     * 撤销返回“撤销成功”
     */
    private boolean cancelSuccess(AlipayTradeCancelResponse response) {
        return response != null &&
                Constants.SUCCESS.equals(response.getCode());
    }

    /**
     * 交易异常，或发生系统错误
     */
    private boolean tradeError(AlipayResponse response) {
        return response == null ||
                Constants.ERROR.equals(response.getCode());
    }
}
